'use strict';

const Generator = require('yeoman-generator');
const genApiModel = require('./api/codegen');
const shecaFont = require('./welcome');
const welcomeFont = require('./welcome');

// 导出自定义Generator, 使用 yo 命令生成
module.exports = class extends Generator {
  constructor(args, opts) {
    super(args, opts);
  }
  async prompting() {
    const answers = await this.prompt([
      {
        type: 'input',
        name: 'name',
        message: '项目名',
        default: 'node-service',
      },
      {
        type: 'input',
        name: 'description',
        message: '项目描述',
      },
      {
        type: 'input',
        name: 'author',
        message: '著作者',
        default: 'DOBE',
      },
      {
        type: 'confirm',
        name: 'needMysql',
        message: 'Mysql模块',
        default: false,
      },
    ]);
    // 配置信息存储
    const randomPath = Math.random() // 生成随机数字, eg: 0.123456
      .toString(36) // 转化成36进制 : "0.4fzyo82mvyr"
      .slice(-8); // yo82mvyr
    const token = Math.random() // 生成随机数字, eg: 0.123456
      .toString(36) // 转化成36进制 : "0.4fzyo82mvyr"
      .slice(-8);
    this.project = {
      ...answers,
      path: randomPath,
      token: randomPath + token,
    };
    this.log(welcomeFont);
    this.log(`
    * 项目名      ${this.project.name}
    * 项目描述    ${this.project.description || '无'}
    * 著作者      ${this.project.author}
    * Mysql模块   ${this.project.needMysql ? '是' : '否'}
    `);
  }
  // 文件生成模块
  paths() {
    // 导入主文件 package.json  app.js
    this._genMainFiles();
    // 生成swagger配置文件夹
    this._genSwaggerFolder();
    // 生成监控配置文件夹;
    this._genPrometheusFolder();
    // 生成Config配置文件夹
    this._genConfigFolder();
    // 生成错误文件夹;
    this._genErrorFolder();
    // 生成日志文件夹
    this._genLogFolder();
    // 生成一个API文件Model 包含 router、service
    this._genRouterFolder(genApiModel());
    if (this.project.needMysql) {
      // 生成mysql配置文件夹
      this._genMysqlFolder();
    }
  }
  _genMainFiles() {
    // package.json
    this.fs.copyTpl(
      this._from('_package.json'),
      this._to('package.json'),
      this.project
    );
    // README.md
    this.fs.copyTpl(
      this._from('README.md'),
      this._to('README.md'),
      this.project
    );

    // start.js
    this.fs.copyTpl(
      this._from('_start.js'),
      this._to('start.js'),
      this.project
    );

    // 启动文件
    this.fs.copyTpl(this._from('app.js'), this._to('app.js'));

    // stage 的pm2 启动
    this.fs.copyTpl(
      this._from('stage.ecosystem.config.js'),
      this._to('stage.ecosystem.config.js'),
      this.project
    );

    // .babelrc
    this.fs.copyTpl(this._from('_babelrc'), this._to('.babelrc'));

    // .eslintrc.js
    this.fs.copyTpl(this._from('_eslintrc.js'), this._to('.eslintrc.js'));

    // .gitignore
    this.fs.copyTpl(this._from('_gitignore'), this._to('.gitignore'));

    // .prettierrc
    this.fs.copyTpl(this._from('_prettierrc'), this._to('.prettierrc'));
  }

  _genMysqlFolder() {
    this.fs.copyTpl(this._from('mysql/index.js'), this._to(`mysql/index.js`));
  }
  _genSwaggerFolder() {
    this.fs.copyTpl(
      this._from('swagger/index.js'),
      this._to(`swagger/index.js`),
      this.project
    );
    this.fs.copyTpl(
      this._from('swagger/usage.md'),
      this._to(`swagger/usage.md`)
    );
  }
  _genPrometheusFolder() {
    this.fs.copyTpl(
      this._from('prometheus/index.js'),
      this._to(`prometheus/index.js`)
    );
    this.fs.copyTpl(
      this._from('prometheus/usage.md'),
      this._to(`prometheus/usage.md`)
    );
    // 图片
    this.fs.copy(
      this._from('prometheus/static/images/jiagoutu.png'),
      this._to(`prometheus/static/images/jiagoutu.png`)
    );
    this.fs.copy(
      this._from('prometheus/static/images/start-server.png'),
      this._to(`prometheus/static/images/start-server.png`)
    );
    this.fs.copy(
      this._from('prometheus/static/images/server-web.png'),
      this._to(`prometheus/static/images/server-web.png`)
    );
    this.fs.copy(
      this._from('prometheus/static/images/start-client.png'),
      this._to(`prometheus/static/images/start-client.png`)
    );
    this.fs.copy(
      this._from('prometheus/static/images/client-log.png'),
      this._to(`prometheus/static/images/client-log.png`)
    );
    this.fs.copy(
      this._from('prometheus/static/images/promtool.png'),
      this._to(`prometheus/static/images/promtool.png`)
    );
  }
  _genConfigFolder() {
    this.fs.copyTpl(
      this._from('config/index.js'),
      this._to(`config/index.js`),
      this.project
    );
    this.fs.copyTpl(
      this._from('config/dev.config.js'),
      this._to(`config/dev.config.js`),
      this.project
    );
    this.fs.copyTpl(
      this._from('config/stage.config.js'),
      this._to(`config/stage.config.js`),
      this.project
    );
    this.fs.copyTpl(
      this._from('config/uat.config.js'),
      this._to(`config/uat.config.js`),
      this.project
    );
    this.fs.copyTpl(
      this._from('config/prod.config.js'),
      this._to(`config/prod.config.js`),
      this.project
    );
  }
  _genErrorFolder() {
    this.fs.copyTpl(this._from('error/index.js'), this._to(`error/index.js`));
  }
  _genLogFolder() {
    this.fs.copyTpl(this._from('logger/index.js'), this._to(`logger/index.js`));
    this.fs.copy(this._from('logger/usage.md'), this._to(`logger/usage.md`));
  }
  _genRouterFolder(apiModel) {
    // 每个路由文件
    const routerModels = apiModel.routerModels;
    for (const routerModel of routerModels) {
      this.fs.copyTpl(
        this._from('router/module/router.js'),
        this._to(`router/${routerModel.baseUrl}/${routerModel.name}.js`),
        routerModel
      );
    }
    // 每个路由对应的service文件
    const serviceModels = apiModel.serviceModels;
    for (const serviceModel of serviceModels) {
      this.fs.copyTpl(
        this._from('service/service.js'),
        this._to(`service/${serviceModel.baseUrl}/${serviceModel.name}.js`),
        serviceModel
      );
    }
    // 每个主模块 index 文件
    const routerIndexModels = apiModel.routerIndexModels;
    for (const routerIndexModel of routerIndexModels) {
      this.fs.copyTpl(
        this._from('router/module/index.js'),
        this._to(`router/${routerIndexModel.baseUrl}/index.js`),
        routerIndexModel
      );
    }
    // 路由 debug
    this.fs.copyTpl(
      this._from('router/debug/index.js'),
      this._to(`router/debug/index.js`),
      this.project
    );
    // 路由 index 文件
    this.fs.copyTpl(
      this._from('router/index.js'),
      this._to(`router/index.js`),
      apiModel.indexModel
    );
    // 中间件 - 参数配置列表
    this.fs.copyTpl(
      this._from('router/middleware/args.config.js'),
      this._to(`router/middleware/args.config.js`),
      apiModel.allArgsModels
    );
    // 中间件 - 参数校验
    this.fs.copyTpl(
      this._from('router/middleware/checkArgs.js'),
      this._to(`router/middleware/checkArgs.js`)
    );
    // 中间件 - 接口鉴权
    this.fs.copyTpl(
      this._from('router/middleware/authorize.js'),
      this._to(`router/middleware/authorize.js`)
    );
    // 中间件 - index.js
    this.fs.copyTpl(
      this._from('router/middleware/index.js'),
      this._to(`router/middleware/index.js`)
    );
    // 统一返回结果 - result/index.js
    this.fs.copyTpl(
      this._from('router/result/index.js'),
      this._to(`router/result/index.js`)
    );
    // swagger - 文档
    this.fs.copyTpl(
      this._from('router/swagger.js'),
      this._to(`router/swagger.js`),
      apiModel.swaggerModel
    );
  }
  // 模板文件路径
  _from(filename) {
    return this.templatePath(filename);
  }
  // 生成文件路径
  _to(filename) {
    if (filename) {
      return this.destinationPath(`project/${filename}`);
    }
    return this.destinationRoot();
  }
};
